using System;
using System.Runtime.Serialization;

namespace BanZuiCloudControlAgent.Utils.Exceptions
{
    /// <summary>
    /// 配置相关异常类，用于表示配置加载、保存、访问等过程中发生的错误
    /// </summary>
    [Serializable]
    public class ConfigurationException : BanZuiException
    {
        /// <summary>
        /// 配置错误类型
        /// </summary>
        public ConfigErrorType ErrorType { get; }

        /// <summary>
        /// 配置键（如果适用）
        /// </summary>
        public string ConfigKey { get; }

        /// <summary>
        /// 初始化ConfigurationException类的新实例
        /// </summary>
        public ConfigurationException() : base("E400", "Configuration", "配置操作发生错误")
        {
            ErrorType = ConfigErrorType.Unknown;
            ConfigKey = null;
        }

        /// <summary>
        /// 使用指定的错误消息初始化ConfigurationException类的新实例
        /// </summary>
        /// <param name="message">描述错误的消息</param>
        public ConfigurationException(string message) : base("E400", "Configuration", message)
        {
            ErrorType = ConfigErrorType.Unknown;
            ConfigKey = null;
        }

        /// <summary>
        /// 使用指定的错误消息和内部异常初始化ConfigurationException类的新实例
        /// </summary>
        /// <param name="message">描述错误的消息</param>
        /// <param name="innerException">导致当前异常的异常</param>
        public ConfigurationException(string message, Exception innerException) : base("E400", "Configuration", message, false, innerException)
        {
            ErrorType = ConfigErrorType.Unknown;
            ConfigKey = null;
        }

        /// <summary>
        /// 使用指定的错误类型和消息初始化ConfigurationException类的新实例
        /// </summary>
        /// <param name="errorType">配置错误类型</param>
        /// <param name="message">描述错误的消息</param>
        public ConfigurationException(ConfigErrorType errorType, string message) : base(GetErrorCode(errorType), "Configuration", message)
        {
            ErrorType = errorType;
            ConfigKey = null;
        }

        /// <summary>
        /// 使用指定的错误类型、消息和内部异常初始化ConfigurationException类的新实例
        /// </summary>
        /// <param name="errorType">配置错误类型</param>
        /// <param name="message">描述错误的消息</param>
        /// <param name="innerException">导致当前异常的异常</param>
        public ConfigurationException(ConfigErrorType errorType, string message, Exception innerException) : base(GetErrorCode(errorType), "Configuration", message, false, innerException)
        {
            ErrorType = errorType;
            ConfigKey = null;
        }

        /// <summary>
        /// 使用指定的错误类型、配置键和消息初始化ConfigurationException类的新实例
        /// </summary>
        /// <param name="errorType">配置错误类型</param>
        /// <param name="configKey">配置键</param>
        /// <param name="message">描述错误的消息</param>
        public ConfigurationException(ConfigErrorType errorType, string configKey, string message) : base(GetErrorCode(errorType), "Configuration", message)
        {
            ErrorType = errorType;
            ConfigKey = configKey;
        }

        /// <summary>
        /// 使用指定的错误类型、配置键、消息和内部异常初始化ConfigurationException类的新实例
        /// </summary>
        /// <param name="errorType">配置错误类型</param>
        /// <param name="configKey">配置键</param>
        /// <param name="message">描述错误的消息</param>
        /// <param name="innerException">导致当前异常的异常</param>
        public ConfigurationException(ConfigErrorType errorType, string configKey, string message, Exception innerException) : base(GetErrorCode(errorType), "Configuration", message, false, innerException)
        {
            ErrorType = errorType;
            ConfigKey = configKey;
        }

        /// <summary>
        /// 使用序列化数据初始化ConfigurationException类的新实例
        /// </summary>
        /// <param name="info">SerializationInfo，它存有关于所引发的异常的序列化的对象数据</param>
        /// <param name="context">包含有关源或目标的上下文信息</param>
        protected ConfigurationException(SerializationInfo info, StreamingContext context) : base(info, context)
        {
            ErrorType = (ConfigErrorType)info.GetInt32("ErrorType");
            ConfigKey = info.GetString("ConfigKey");
        }

        /// <summary>
        /// 使用可序列化的数据填充SerializationInfo
        /// </summary>
        /// <param name="info">要填充数据的SerializationInfo</param>
        /// <param name="context">此序列化的目标</param>
        public override void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            base.GetObjectData(info, context);
            info.AddValue("ErrorType", (int)ErrorType);
            info.AddValue("ConfigKey", ConfigKey);
        }

        /// <summary>
        /// 获取包含错误代码、配置键的完整错误消息
        /// </summary>
        /// <returns>包含错误代码、配置键的完整错误消息</returns>
        public override string ToString()
        {
            if (string.IsNullOrEmpty(ConfigKey))
            {
                return base.ToString();
            }
            return $"[{ErrorCode}] {Module} (Key: {ConfigKey}): {Message}";
        }

        /// <summary>
        /// 根据配置错误类型获取错误代码
        /// </summary>
        /// <param name="errorType">配置错误类型</param>
        /// <returns>错误代码</returns>
        private static string GetErrorCode(ConfigErrorType errorType)
        {
            switch (errorType)
            {
                case ConfigErrorType.FileNotFound:
                    return "E401";
                case ConfigErrorType.InvalidFormat:
                    return "E402";
                case ConfigErrorType.AccessDenied:
                    return "E403";
                case ConfigErrorType.KeyNotFound:
                    return "E404";
                case ConfigErrorType.TypeConversionFailed:
                    return "E405";
                case ConfigErrorType.SaveFailed:
                    return "E406";
                case ConfigErrorType.LoadFailed:
                    return "E407";
                case ConfigErrorType.InvalidEnvironment:
                    return "E408";
                default:
                    return "E400";
            }
        }
    }

    /// <summary>
    /// 配置错误类型枚举
    /// </summary>
    public enum ConfigErrorType
    {
        /// <summary>
        /// 未知错误
        /// </summary>
        Unknown = 0,

        /// <summary>
        /// 配置文件未找到
        /// </summary>
        FileNotFound = 1,

        /// <summary>
        /// 配置格式无效
        /// </summary>
        InvalidFormat = 2,

        /// <summary>
        /// 访问被拒绝
        /// </summary>
        AccessDenied = 3,

        /// <summary>
        /// 配置键未找到
        /// </summary>
        KeyNotFound = 4,

        /// <summary>
        /// 类型转换失败
        /// </summary>
        TypeConversionFailed = 5,

        /// <summary>
        /// 保存失败
        /// </summary>
        SaveFailed = 6,

        /// <summary>
        /// 加载失败
        /// </summary>
        LoadFailed = 7,

        /// <summary>
        /// 无效的环境
        /// </summary>
        InvalidEnvironment = 8
    }
} 